crates.io: Use cache + origin request policies for webapp CloudFront#1069
Merged
marcoieni merged 1 commit intoJun 4, 2026
Merged
Conversation
Replace the legacy `forwarded_values` block with a dedicated cache policy and origin request policy. Cookies, User-Agent, Referer, X-Request-Id, and Authorization are forwarded to the origin without being part of the cache key, so authenticated and per-session requests no longer fragment the cache. Accept stays in the cache key for content negotiation, and Accept-Encoding is normalized via the compression settings. TTLs are unchanged (0/0/1y).
Member
Author
|
@rust-lang/infra any thoughts on this? should we try this out on staging? |
Member
|
the changes look good. I applied to staging. Let me know if you want me to apply to prod 👍 |
Member
Author
|
I had Claude verify the cache key behavior against https://cloudfront-app.crates.io/ (old) and https://cloudfront-app.staging.crates.io/ (new) via Test Script Code#!/usr/bin/env python3
"""Probe which request attributes are part of the CloudFront cache key.
Technique: carve out a private cache entry with a unique query-string token
(query string is in the cache key on both configs), warm it with value A until
it returns a HIT, then flip to value B. A MISS on B means the attribute
contributes to the cache key; a HIT means it does not.
"""
import http.client
import random
import time
UA = "crates-cache-test (tobias@bieniek.cloud)"
PATH = "/_app/immutable/chunks/kNaey6uv.js"
DOMAINS = ["cloudfront-app.crates.io", "cloudfront-app.staging.crates.io"]
def get_xcache(domain, qs, headers):
"""Return the X-Cache header value for one request."""
conn = http.client.HTTPSConnection(domain, timeout=20)
h = {"User-Agent": UA}
h.update(headers)
conn.request("GET", f"{PATH}?{qs}", headers=h)
resp = conn.getresponse()
resp.read()
xc = resp.getheader("X-Cache", "<none>")
conn.close()
return xc
def classify(b):
if b.startswith("Miss"):
return "IN cache key"
if b.startswith("Hit") or b.startswith("RefreshHit"):
return "NOT in cache key"
return f"?? ({b})"
def probe(name, a_headers, b_headers):
print(f"== {name} ==")
for domain in DOMAINS:
qs = f"probe-{random.randint(0, 10**12)}"
a1 = get_xcache(domain, qs, a_headers)
time.sleep(1)
a2 = get_xcache(domain, qs, a_headers)
b = get_xcache(domain, qs, b_headers)
print(f" {domain:<34} A=[{a1} | {a2}] B=[{b}] -> {classify(b)}")
print()
probe("Accept", {"Accept": "application/json"}, {"Accept": "text/html"})
probe("Referer", {"Referer": "https://a.example/"}, {"Referer": "https://b.example/"})
# both User-Agent values must be valid custom UAs, else crates.io returns 403
probe(
"User-Agent",
{"User-Agent": "crates-cache-test-A (tobias@bieniek.cloud)"},
{"User-Agent": "crates-cache-test-B (tobias@bieniek.cloud)"},
)
probe("X-Request-Id", {"X-Request-Id": "aaaaaaaa"}, {"X-Request-Id": "bbbbbbbb"})
probe(
"Authorization",
{"Authorization": "Bearer tokenA"},
{"Authorization": "Bearer tokenB"},
)
probe("Cookie", {"Cookie": "probe=a"}, {"Cookie": "probe=b"})
probe("Accept-Encoding", {"Accept-Encoding": "gzip"}, {"Accept-Encoding": "br"})in other words: this looks like it works as intended and I guess we can put this onto prod :) |
Member
|
applied to prod 👍 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the legacy
forwarded_valuesblock with a dedicated cache policy and origin request policy. Cookies, User-Agent, Referer, X-Request-Id, and Authorization are forwarded to the origin without being part of the cache key, so authenticated and per-session requests no longer fragment the cache. Accept stays in the cache key for content negotiation, and Accept-Encoding is normalized via the compression settings. TTLs are unchanged (0/0/1y).Created with the help of Claude Code, which:
forwarded_valuescache key and identified that cookies, User-Agent, and Authorization were fragmenting the cache,